package com.hxhy.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author gbzdyf@126.com
 * @Create: 2019/11/27 16:53
 */
public class RSADemo {


	/**
	 * RSA最大加密明文大小
	 */
	private static final int MAX_ENCRYPT_BLOCK = 117;


	/**
	 * 默认字符集编码
	 */
	private static final String DEFAULT_CHARSET = "UTF-8";

	/**
	 * RSA加密
	 *
	 * @param data
	 *            待加密数据
	 * @param publicKey
	 *            公钥
	 * @return
	 * @author pcheng
	 * @date 2018-6-25
	 */
	public static String encrypt(String data, PublicKey publicKey) throws Exception {
		Cipher cipher = Cipher.getInstance("RSA");
		cipher.init(Cipher.ENCRYPT_MODE, publicKey);
		int inputLen = data.getBytes(DEFAULT_CHARSET).length;
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		int offSet = 0;
		byte[] cache;
		int i = 0;
		// 对数据分段加密
		while (inputLen - offSet > 0) {
			if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
				cache = cipher.doFinal(data.getBytes(DEFAULT_CHARSET), offSet, MAX_ENCRYPT_BLOCK);
			} else {
				cache = cipher.doFinal(data.getBytes(DEFAULT_CHARSET), offSet, inputLen - offSet);
			}
			out.write(cache, 0, cache.length);
			i++;
			offSet = i * MAX_ENCRYPT_BLOCK;
		}
		byte[] encryptedData = out.toByteArray();
		out.close();
		/* 获取加密内容以UTF-8为标准转化的字节进行加密后再使用base64编码成字符串 */
		/* 加密后的字符串 */
		return Base64.encodeBase64String(encryptedData);
	}

	/**
	 * 获取公钥
	 *
	 * @return 公钥对象
	 * @throws Exception
	 */
	public static PublicKey getPublickey(String publicKey) throws Exception {
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes()));
		return keyFactory.generatePublic(bobPubKeySpec);
	}
}